package top.archiesean.common.security.service;

import org.springframework.core.Ordered;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.CollectionUtils;
import top.archiesean.admin.dto.UserInfo;
import top.archiesean.admin.pojo.SysUser;
import top.archiesean.common.core.constant.SecurityConstants;
import top.archiesean.common.core.domain.R;
import top.archiesean.common.security.domain.SeanUser;

import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author ArchieSean
 * @description 此处用于扩展
 * @date 2024-01-11 07:52
 */
public interface SeanUserDetailsService extends UserDetailsService, Ordered {

    /**
     * 是否支持此客户端校验
     *
     * @param clientId 目标客户端
     * @return true/false
     */
    default boolean support(String clientId, String grantType) {
        return true;
    }

    /**
     * 排序值 默认取最大的
     *
     * @return 排序值
     */
    default int getOrder() {
        return 0;
    }

    /**
     * 通过用户实体查询
     *
     * @param user user
     * @return
     */
    default UserDetails loadUserByUser(SeanUser user) {
        return this.loadUserByUsername(user.getUsername());
    }


    /**
     * 用于构建提供给security的UserDetails
     *
     * @param result feign调用的结果
     * @return obj
     */
    default UserDetails getUserDetails(R<UserInfo> result) {
        UserInfo userInfo = Optional.of(result)
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在"))
                .getData();

        userInfo = Optional.of(userInfo).orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
        //获取角色
        Set<String> dbAuthsSet = new HashSet<>();
        if (!CollectionUtils.isEmpty(userInfo.getRoles())) {
            dbAuthsSet = userInfo.getRoles().stream().map(role -> {
                if (!role.startsWith(SecurityConstants.ROLE)) {
                    role = SecurityConstants.ROLE + role;
                }
                return role;
            }).collect(Collectors.toSet());
        }
        //获取方法权限
        if (!CollectionUtils.isEmpty(userInfo.getPermissions())) {
            dbAuthsSet.addAll(userInfo.getPermissions());
        }

        List<GrantedAuthority> list = AuthorityUtils.createAuthorityList(dbAuthsSet);
        SysUser sysUser = userInfo.getSysUser();

        //构建security 用户
        return new SeanUser(sysUser.getId(), sysUser.getDeptId(), sysUser.getUsername(), sysUser.getPassword(),
                sysUser.getPhone(), true, true, true, true, list);
    }

}
